/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.connector.service.impl;

import com.google.common.collect.Lists;
import com.je.common.base.message.ButtonScriptBuilder;
import com.je.common.base.message.vo.*;
import com.je.connector.base.message.model.Notice;
import com.je.connector.base.message.model.*;
import com.je.connector.service.AbstractPushServiceImpl;
import com.je.connector.service.PushService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class PushServiceImpl extends AbstractPushServiceImpl implements PushService {

    @Override
    public void sendMsg(String userId, PushMessage message) {
        if (message instanceof PushSystemMessage) {
            sendSystemMsg(userId, (PushSystemMessage) message);
        } else if (message instanceof PushScriptMessage) {
            sendScriptMsg(userId, (PushScriptMessage) message);
        } else if (message instanceof PushNoReadMessage) {
            sendNoReadMsg(userId, (PushNoReadMessage) message);
        } else if (message instanceof PushNoticeMessage) {
            sendNoticeMsg(userId, (PushNoticeMessage) message);
        }
    }

    @Override
    public void sendMsg(List<String> userIdList, PushMessage message) {
        if (message instanceof PushSystemMessage) {
            sendSystemMsg(userIdList, (PushSystemMessage) message);
        } else if (message instanceof PushScriptMessage) {
            sendScriptMsg(userIdList, (PushScriptMessage) message);
        } else if (message instanceof PushNoReadMessage) {
            sendNoReadMsg(userIdList, (PushNoReadMessage) message);
        } else if (message instanceof PushNoticeMessage) {
            sendNoticeMsg(userIdList, (PushNoticeMessage) message);
        } else {
            sendOtherSystemMsg(userIdList, message);
        }
    }

    @Override
    public void sendNoReadMsg(String userId, PushNoReadMessage message) {
        JECloudNoReadMessage jeCloudNoReadMessage = new JECloudNoReadMessage(message.getBusType());
        recursiveNoReadMsg(jeCloudNoReadMessage, message);
        sendToConnection(Lists.newArrayList(userId), JECloudNoReadMessage.buildPacket(jeCloudNoReadMessage));
    }

    @Override
    public void sendNoReadMsg(List<String> userIdList, PushNoReadMessage message) {
        JECloudNoReadMessage jeCloudNoReadMessage = new JECloudNoReadMessage(message.getBusType());
        recursiveNoReadMsg(jeCloudNoReadMessage, message);
        sendToConnection(userIdList, JECloudNoReadMessage.buildPacket(jeCloudNoReadMessage));
    }

    @Override
    public void sendSystemMsg(String userId, PushSystemMessage message) {
        JECloudSystemMessage systemMessage = new JECloudSystemMessage(message.getBusType(), message.getContent());
        sendToConnection(Lists.newArrayList(userId), JECloudSystemMessage.buildPacket(systemMessage));
    }

    @Override
    public void sendSystemMsg(List<String> userIdList, PushSystemMessage message) {
        JECloudSystemMessage systemMessage = new JECloudSystemMessage(message.getBusType(), message.getContent());
        sendToConnection(userIdList, JECloudSystemMessage.buildPacket(systemMessage));
    }

    @Override
    public void sendOtherSystemMsg(List<String> userIdList, PushMessage message) {
        JECloudSystemMessage systemMessage = new JECloudSystemMessage(message.getBusType(), (String) message.getContent());
        sendToConnection(userIdList, JECloudSystemMessage.buildPacket(systemMessage));
    }

    @Override
    public void sendScriptMsg(String userId, PushScriptMessage message) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(message.getBusType(), message.getContent());
        scriptMessage.setScript(message.getScript());
        scriptMessage.setParams(message.getParams());
        sendToConnection(Lists.newArrayList(userId), JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendScriptMsg(List<String> userIdList, PushScriptMessage message) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(message.getBusType(), message.getContent());
        scriptMessage.setScript(message.getScript());
        scriptMessage.setParams(message.getParams());
        sendToConnection(userIdList, JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendScriptOpenFuncGridMsg(String userId, String funcCode, String busType, String content) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(busType, content);
        scriptMessage.setScript(ButtonScriptBuilder.buildOpenFuncGridScript(funcCode));
        sendToConnection(Lists.newArrayList(userId), JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendScriptOpenFuncGridMsg(List<String> userIdList, String funcCode, String busType, String content) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(busType, content);
        scriptMessage.setScript(ButtonScriptBuilder.buildOpenFuncGridScript(funcCode));
        sendToConnection(userIdList, JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendScriptOpenFuncFormMsg(String userId, String funcCode, String busType, String content, String beanId) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(busType, content);
        scriptMessage.setScript(ButtonScriptBuilder.buildOpenFuncFormScript(funcCode, beanId));
        sendToConnection(Lists.newArrayList(userId), JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendScriptOpenFuncFormMsg(List<String> userIdList, String funcCode, String busType, String content, String beanId) {
        JECloudScriptMessage scriptMessage = new JECloudScriptMessage(busType, content);
        scriptMessage.setScript(ButtonScriptBuilder.buildOpenFuncFormScript(funcCode, beanId));
        sendToConnection(userIdList, JECloudScriptMessage.buildPacket(scriptMessage));
    }

    @Override
    public void sendNoticeMsg(String userId, PushNoticeMessage message) {
        sendNoticeMsg(Lists.newArrayList(userId), message);
    }

    @Override
    public void sendNoticeMsg(List<String> userIdList, PushNoticeMessage message) {
        JECloudNoticeMessage jeCloudNoticeMessage = new JECloudNoticeMessage();
        jeCloudNoticeMessage.setBusKey(message.getBusType());
        jeCloudNoticeMessage.setContent(convertNotice(message.getContent()));
        sendToConnection(userIdList, JECloudNoticeMessage.buildPacket(jeCloudNoticeMessage));
    }

    @Override
    public void sendNoticeOpenFuncGridMsg(String userId, String funcCode, String busType, com.je.common.base.message.vo.Notice content) {
        sendNoticeOpenFuncGridMsg(Lists.newArrayList(userId), funcCode, busType, content);
    }

    @Override
    public void sendNoticeOpenFuncGridMsg(List<String> userIdList, String funcCode, String busType, com.je.common.base.message.vo.Notice content) {
        JECloudNoticeMessage jeCloudNoticeMessage = new JECloudNoticeMessage();
        jeCloudNoticeMessage.setBusKey(busType);
        Notice notice = convertNotice(content);
        notice.getButtons().add(buildOpenFuncGridNoticeButton(funcCode));
        jeCloudNoticeMessage.setContent(notice);
        sendToConnection(userIdList, JECloudNoticeMessage.buildPacket(jeCloudNoticeMessage));
    }

    @Override
    public void sendNoticeOpenFuncFormMsg(String userId, String funcCode, String busType, com.je.common.base.message.vo.Notice content, String beanId) {
        sendNoticeOpenFuncFormMsg(Lists.newArrayList(userId), funcCode, busType, content, beanId);
    }

    @Override
    public void sendNoticeOpenFuncFormMsg(List<String> userIdList, String funcCode, String busType, com.je.common.base.message.vo.Notice content, String beanId) {
        JECloudNoticeMessage jeCloudNoticeMessage = new JECloudNoticeMessage();
        jeCloudNoticeMessage.setBusKey(busType);
        Notice notice = convertNotice(content);
        notice.getButtons().add(buildOpenFuncFormNoticeButton(funcCode, beanId));
        jeCloudNoticeMessage.setContent(notice);
        sendToConnection(userIdList, JECloudNoticeMessage.buildPacket(jeCloudNoticeMessage));
    }

    private Notice.NoticeButton buildOpenFuncGridNoticeButton(String funcCode) {
        Notice.NoticeButton button = new Notice.NoticeButton();
        button.setText("查看");
        button.setScript(ButtonScriptBuilder.buildOpenFuncGridScript(funcCode));
        return button;
    }

    private Notice.NoticeButton buildOpenFuncFormNoticeButton(String funcCode, String beanId) {
        Notice.NoticeButton button = new Notice.NoticeButton();
        button.setText("查看");
        button.setScript(ButtonScriptBuilder.buildOpenFuncFormScript(funcCode, beanId));
        return button;
    }

    private void recursiveNoReadMsg(JECloudMessage jeCloudMessage, PushMessage message) {
        jeCloudMessage.setBusKey(message.getBusType());
        if (MessageType.SYS_MESSAGE_TYPE.equals(message.getType())) {
            jeCloudMessage.setContent(message.getContent());
        } else if (MessageType.SCRIPT_MESSAGE_TYPE.equals(message.getType())) {
            ((JECloudScriptMessage) jeCloudMessage).setScript(((PushScriptMessage) message).getScript());
            ((JECloudScriptMessage) jeCloudMessage).setParams(((PushScriptMessage) message).getParams());
        } else if (MessageType.NOTICE_MESSAGE_TYPE.equals(message.getType())) {
            PushNoticeMessage pushNoticeMessage = (PushNoticeMessage) message;
            jeCloudMessage.setContent(convertNotice(pushNoticeMessage.getContent()));
        } else if (MessageType.NOREAD_MESSAGE_TYPE.equals(message.getType())) {
            PushNoReadMessage pushNoReadMessage = (PushNoReadMessage) message;
            List<PushMessage> contents = pushNoReadMessage.getContent();
            List<JECloudMessage> convertedContents = new ArrayList<>();
            JECloudMessage eachJeCloudMessage;
            for (PushMessage eachPushMessage : contents) {
                if (MessageType.SYS_MESSAGE_TYPE.equals(eachPushMessage.getType())) {
                    eachJeCloudMessage = new JECloudSystemMessage(eachPushMessage.getBusType(), (String) eachPushMessage.getContent());
                } else if (MessageType.SCRIPT_MESSAGE_TYPE.equals(eachPushMessage.getType())) {
                    eachJeCloudMessage = new JECloudScriptMessage(eachPushMessage.getBusType(), (String) eachPushMessage.getContent());
                } else {
                    eachJeCloudMessage = new JECloudNoReadMessage(eachPushMessage.getBusType());
                    recursiveNoReadMsg(eachJeCloudMessage, eachPushMessage);
                }
                convertedContents.add(eachJeCloudMessage);
            }
            jeCloudMessage.setContent(convertedContents);
        }
    }

    private Notice convertNotice(com.je.common.base.message.vo.Notice notice) {
        Notice targetNotice = new Notice();
        targetNotice.setCloseable(notice.isCloseable());
        targetNotice.setDuration(notice.getDuration());
        targetNotice.setPlacement(notice.getPlacement());
        targetNotice.setStatus(notice.getStatus());
        targetNotice.setTitle(notice.getTitle());
        targetNotice.setContent(notice.getContent());
        targetNotice.setPlayAudio(notice.isPlayAudio());
        targetNotice.setNowTime(notice.getNowTime());
        List<Notice.NoticeButton> buttons = new ArrayList<>();
        if (notice.getButtons() != null && !notice.getButtons().isEmpty()) {
            for (com.je.common.base.message.vo.Notice.NoticeButton eachButton : notice.getButtons()) {
                buttons.add(convertButton(eachButton));
            }
        }
        targetNotice.setButtons(buttons);
        return targetNotice;
    }

    private Notice.NoticeButton convertButton(com.je.common.base.message.vo.Notice.NoticeButton noticeButton) {
        Notice.NoticeButton eachTargetButton = new Notice.NoticeButton();
        eachTargetButton.setScript(noticeButton.getScript());
        eachTargetButton.setParams(noticeButton.getParams());
        eachTargetButton.setBgColor(noticeButton.getBgColor());
        eachTargetButton.setBorderColor(noticeButton.getBorderColor());
        eachTargetButton.setIcon(noticeButton.getIcon());
        eachTargetButton.setFontColor(noticeButton.getFontColor());
        eachTargetButton.setIconColor(noticeButton.getIconColor());
        eachTargetButton.setText(noticeButton.getText());
        return eachTargetButton;
    }

}
